/**
* Copyright (C) 2007 Pedro Miller Rabinovitch.
* http://www.opensource.org/licenses/mit-license.php
*
* Basically, feel free to use it however you want to.
* Please give me credit where appropriate.
*
* Pedro "Shade" Miller, gmail user: pedromr
* http://exodia.org
*
* @author Miller
*
* $Id: TestWorld.as 8 2007-12-13 10:26:42Z pedromr $
*/
package org.exodia.seeds {
	import fl.controls.Button;
	import fl.events.ComponentEvent;
	import flash.display.Graphics;
	import flash.display.MovieClip;
	import flash.display.SpreadMethod;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	import flash.utils.getTimer;
	import org.exodia.seeds.sprites.WorldShape;
	import org.exodia.seeds.model.World;
	import org.exodia.seeds.model.Agent;
	import org.exodia.seeds.sprites.AgentShape;
	import org.exodia.seeds.behaviours.*;
	import org.exodia.math.Vector3D;

	public class TestWorld extends MovieClip {
		var _world:World;
		var _worldShape:WorldShape;
		
		var _timer:Timer;
		var _timeLastTick:uint;
		
		var _followBehaviour:SeekBehaviour;
		var _targetedBehaviour:SeekBehaviour;
		var _randWalkBehaviour:RandomWalkBehaviour;
		var _separationBehaviour:SeparationBehaviour;
		
		var targetMark:Sprite;
		var _leader:Agent;
		
		public function TestWorld() {
			_world = new World();
			var margin:Number = 20;
			var panelWidth:Number = 150;
			_world.width = stage.stageWidth - 3*margin - panelWidth;
			_world.height = stage.stageHeight - 2*margin;
			_worldShape = new WorldShape(_world);
			addChild( _worldShape );
			_worldShape.x = panelWidth+2*margin;
			_worldShape.y = margin;
			
			
			var lastUIy:Number = margin;
			
			var btnPause:Button = new Button();
			btnPause.width = panelWidth;
			btnPause.label = "Pause";
			btnPause.addEventListener( ComponentEvent.BUTTON_DOWN, function( evt:ComponentEvent) {
				if( _timer.running ) {
					_timer.stop()
					btnPause.label = "Resume";
				} else {
					_timeLastTick = 0;
					_timer.start()
					btnPause.label = "Pause";
				}
			});
			btnPause.x = margin;
			btnPause.y = lastUIy;
			addChild( btnPause );
			lastUIy = btnPause.y + btnPause.height;
			
			
			
			targetMark = new Sprite();
			var g:Graphics = targetMark.graphics;
			g.lineStyle( 1, 0 );
			var r:Number = 5;
			var l:Number = r * 1.5;
			g.drawCircle( 0.5, 0.5, r );
			g.moveTo( -l,  0 );
			g.lineTo(  l,  0 );
			g.moveTo(  0, -l );
			g.lineTo(  0,  l );
			_worldShape.addChild( targetMark );
			
			//_worldShape.visible = false;
			
			_worldShape.addEventListener( MouseEvent.CLICK, handleClick );
			_worldShape.addEventListener( MouseEvent.MOUSE_MOVE, handleMouseMove );
			
			_randWalkBehaviour = new RandomWalkBehaviour( 0.1, 4000 );
			_separationBehaviour = new SeparationBehaviour( 1.5 );
			_followBehaviour = new SeekBehaviour( 1 );
			_targetedBehaviour = new SeekBehaviour( 2 );
			
			var range:Number = 75;
			var nAgents:uint = 30;
			
			for( var i:int = 0; i < nAgents; i++ ) {
				var agent:Agent = new Agent( _world );
				var agentShape:AgentShape = new AgentShape( agent );
				
				agent.radius = 8;
				agent.maxSpeed = 0.08;
				agent.maxForce = 0.0001;
				agent.sensorRangeSquared = range*range;
				
				agent.addBehaviour( _randWalkBehaviour );
				agent.addBehaviour( _separationBehaviour );
				/**/
				if ( i == 0 ) {
					_leader = agent;
					agent.radius = 10;
					agent.addBehaviour( _targetedBehaviour );
					agentShape.rgbFillColor = 0xC5FEE2;
				} else {
					if ( i == 1 )
						agent.radius = 20;
					agent.addBehaviour( _followBehaviour );
				}
				/**/
				
				agent.position.x = _world.width/2 + (Math.random()-0.5) * _world.width * 0.9;
				agent.position.y = _world.height/2 + (Math.random()-0.5) * _world.height * 0.9;
				_worldShape.addAgentShape( agentShape );
				
				agentShape.addEventListener( MouseEvent.CLICK, handleAgentClicked );
				agentShape.buttonMode = true;
				
			}
						
			
			_timeLastTick = getTimer();
			_timer = new Timer( 1000 / 30 );
			_timer.addEventListener( TimerEvent.TIMER, handleTimerTick );
			_timer.start();
		}
		
		function handleTimerTick( evt:TimerEvent ) {
			var now:uint = getTimer();
			var deltaMS:uint = now - _timeLastTick;
			
			if( _timeLastTick != 0 ) {
				if( _leader )
					_followBehaviour.setTarget( _leader.position );
				
				_world.tick( deltaMS );
				stage.invalidate();
			}
			
			_timeLastTick = now;
		}
		
		function handleClick( evt:MouseEvent ) {
			var pt:Vector3D = new Vector3D( _worldShape.mouseX, _worldShape.mouseY );
			_targetedBehaviour.setTarget( pt );
			targetMark.x = pt.x;
			targetMark.y = pt.y;
			//trace( "CLICK " + pt );
		}
		function handleMouseMove( evt:MouseEvent ) {
			if ( !evt.buttonDown )
				return;
				
			var pt:Vector3D = new Vector3D( _worldShape.mouseX, _worldShape.mouseY );
			_targetedBehaviour.setTarget( pt );
			targetMark.x = pt.x;
			targetMark.y = pt.y;
			//trace( "CLICK " + pt );
		}
		
		function handleAgentClicked( evt:MouseEvent ) {
			var agent:AgentShape = evt.target as AgentShape;
			
			agent._drawNeighbours = !agent._drawNeighbours;
			agent._drawRadius = !agent._drawRadius;
		}
	}
	
}
